#pragma once

#include <set>
#include <chrono>


#include "config.h"

#include "Message.hpp"
#include "EntityBase.h"
#include "EntityManager.hpp"

namespace walker_sm
{
	class MessageManager
	{
	public:
		static MessageManager* GetInstance()
		{
			static MessageManager instance;
			return &instance;
		}

		void DispathMessage(double delay, int msgID, int sender, int reciver, void* extraInfo)
		{
			Message msg(0, msgID, sender, reciver, extraInfo);

			if(delay <= SEND_MSG_IMMEDIATELY)
			{
				DispathMessage(msg);
			}
			else
			{
				msg.timeStamp=std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()) + delay;
				priorityQue.insert(msg);
			}
		}

		void Update()
		{
			auto currentTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
			while(!priorityQue.empty()&&priorityQue.begin()->timeStamp<=currentTime)
			{
				auto it=priorityQue.begin();
				DispathMessage(*it);
				priorityQue.erase(it);
			}
		}


	private:
		MessageManager() { }
		MessageManager(const MessageManager&) { }
		MessageManager& operator=(const MessageManager&) { }

		void DispathMessage(const Message& msg)
		{
			auto entity = EntityManager::GetInstance()->GetEntityById(msg.reciverId);
			entity->HandleMessage(msg);
		}

	private:
		std::set<Message> priorityQue;
	};
}
